package com.project.app;

import android.app.AlertDialog;
import android.content.DialogInterface;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.RequiresApi;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.webkit.JsPromptResult;
import android.webkit.JsResult;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Toast;

import com.project.app.bean.AndroidToJs;

import org.androidannotations.annotations.EActivity;
import org.androidannotations.annotations.ViewById;

import java.util.HashMap;
import java.util.Set;

@EActivity
public class JsCallAndroidActivity extends AppCompatActivity {

    @ViewById(R.id.web_View)
    WebView webView;
    private StringBuffer buffer;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_js_call_web);

//        webView = findViewById(R.id.web_View);
        WebSettings webSettings = webView.getSettings();
        /** 允许与js交互*/
        webSettings.setJavaScriptEnabled(true);
        /** 允许JS弹窗*/
        webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
//        webView.loadData("","text/html","UTF-8");
//        webView.loadUrl("https://www.baidu.com");
//        webView.setWebViewClient(new MyWebViewClient());

//        第一种方法：
        // 通过addJavascriptInterface()将Java对象映射到JS对象
        //参数1：Javascript对象名
        //参数2：Java对象名
        webView.addJavascriptInterface(new AndroidToJs(), "test");
        webView.loadUrl("file:///android_asset/js_call_android.html");


//        第二种方法
//        / 复写WebViewClient类的shouldOverrideUrlLoading方法
        setWebViewClient();

        //第三种方法
        setWebChromeClient();


        /**
         *
         *
         * 无论是第二种方法、还是第三种方法 缺点是没有返回值
         *
         */


    }



    private void setWebViewClient() {
        webView.setWebViewClient(new WebViewClient() {
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                // 步骤2：根据协议的参数，判断是否是所需要的url
                // 一般根据scheme（协议格式） & authority（协议名）判断（前两个参数）
                //假定传入进来的 url = "js://webview?arg1=111&arg2=222"（同时也是约定好的需要拦截的）

                Uri uri = Uri.parse(url);
                // 如果url的协议 = 预先约定的 js 协议
                // 就解析往下解析参数
                if (uri.getScheme().equals("js")) {
                    // 如果 authority  = 预先约定协议里的 webview，即代表都符合约定的协议
                    // 所以拦截url,下面JS开始调用Android需要的方法
                    if (uri.getAuthority().equals("webview")) {
                        //  步骤3：
                        // 执行JS所需要调用的逻辑
                        // 可以在协议上带有参数并传递到Android上
                        HashMap<String, String> params = new HashMap<>();
                        Set<String> collection = uri.getQueryParameterNames();
                        Toast.makeText(JsCallAndroidActivity.this, "js调用了Android的方法通过shouldOverrideUrlLoading实现了", Toast.LENGTH_SHORT).show();
                    }

                    return true;
                }
                return super.shouldOverrideUrlLoading(view, url);
            }

        });
    }



    private void setWebChromeClient() {
        webView.setWebChromeClient(new WebChromeClient() {
            // 拦截输入框(原理同方式2)
            // 参数message:代表promt（）的内容（不是url）
            // 参数result:代表输入框的返回值
            @Override
            public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) {
                // 根据协议的参数，判断是否是所需要的url(原理同方式2)
                // 一般根据scheme（协议格式） & authority（协议名）判断（前两个参数）
                //假定传入进来的 url = "js://webview?arg1=111&arg2=222"（同时也是约定好的需要拦截的）
                Uri uri = Uri.parse(message);
                // 如果url的协议 = 预先约定的 js 协议
                // 就解析往下解析参数
                if (uri.getScheme().equals("js")) {
                    // 如果 authority  = 预先约定协议里的 webview，即代表都符合约定的协议
                    // 所以拦截url,下面JS开始调用Android需要的方法
                    if (uri.getAuthority().equals("demo")) {
                        // 可以在协议上带有参数并传递到Android上
                        HashMap<String, String> params = new HashMap<>();
                        Set<String> collection = uri.getQueryParameterNames();

                        //参数result:代表消息框的返回值(输入值) 貌似onJsConfirm 一被重写该方法就无效了
                        result.confirm("js调用了Android的方法通过Prompt实现了");

                    }
                    return true;
                }
                return super.onJsPrompt(view, url, message, defaultValue, result);
            }

            // 通过alert()和confirm()拦截的原理相同，此处不作过多讲述

            // 拦截JS的警告框
            @Override
            public boolean onJsAlert(WebView view, String url, String message, final JsResult result) {
                AlertDialog.Builder b = new AlertDialog.Builder(JsCallAndroidActivity.this);
                b.setTitle("Alert");
                b.setMessage(message);
                b.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        result.confirm();
                    }
                });
                b.setCancelable(false);
                b.create().show();
                return true;
            }


            // 拦截JS的确认框
            @Override
            public boolean onJsConfirm(WebView view, String url, String message, JsResult result) {
                Uri uri = Uri.parse(message);
                if (uri.getScheme().equals("js")){
                    if (uri.getAuthority().equals("confirm")){
                        HashMap<String, String> params = new HashMap<>();
                        Set<String> vaule = uri.getQueryParameterNames();
                        String name  = uri.getQueryParameter("name");
                        String gender = uri.getQueryParameter("gender");
                        String resu = "姓名：" + name + " 性别：" + gender + "年龄：" + 20;
                        Toast.makeText(JsCallAndroidActivity.this,resu , Toast.LENGTH_SHORT).show();

                        //我们可以把组成的结果通过调用evaluateJavascript或loadUrl返回给js
                        buffer = new StringBuffer();
                        buffer.append("javascript:resultBack");
                        buffer.append("(").append("'").append(resu).append("'").append(")");

                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT){
                            webView.post(new Runnable() {
                                @RequiresApi(api = Build.VERSION_CODES.KITKAT)
                                @Override
                                public void run() {
                                    webView.evaluateJavascript(buffer.toString(),null);
                                }
                            });
                        }else {
                            webView.post(new Runnable() {
                                @Override
                                public void run() {
                                    webView.loadUrl(buffer.toString());
                                }
                            });
                        }

                        //返回 true 不在弹出确认框。
                        return true;
                    }else {
                        return super.onJsConfirm(view, url, message, result);
                    }
                }
                return super.onJsConfirm(view, url, message, result);
            }

        });
    }


}
